package me.spring.cloud.common.components.oauth2.userdetails.util;

import me.spring.cloud.common.components.oauth2.userdetails.Oauth2UserDetails;
import me.spring.cloud.common.components.oauth2.userdetails.exception.AuthUserException;
import me.spring.cloud.common.components.response.code.ErrorCode;
import me.spring.cloud.common.components.oauth2.userdetails.exception.code.AuthoritiesCode;

import java.util.LinkedHashMap;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;

/**
 * @author luffy
 */
@Slf4j
public class UserInfoUtil {

    private static final BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();

    public static <T> T getUserInfo(Class<T> cls) {
        Object userInfo = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (null == userInfo || "unknown".equals(userInfo)) {
            throw new AuthUserException(AuthoritiesCode.CLIENT_VALID_TOKEN_ERROR);
        }
        try {
            T t = cls.newInstance();
            BeanUtils.populate(t, (LinkedHashMap<String, Object>) userInfo);
            return t;
        } catch (Exception e) {
            throw new AuthUserException(ErrorCode.FAIL, e);
        }
    }

    public static String encrypt(String password) {
        return encoder.encode(password);
    }

    public static boolean match(String rawPassword, String encodedPassword) {
        return encoder.matches(rawPassword, encodedPassword);
    }

    public static Oauth2UserDetails getOAuthUserDetails() {
        Object userInfo = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        if (userInfo == null) throw new AuthUserException(AuthoritiesCode.Unauthorized);
        if (userInfo instanceof Oauth2UserDetails) return (Oauth2UserDetails) userInfo;
            throw new AuthUserException(ErrorCode.FAIL);

    }
}
